import math

from vector import Vector
from force_generator import ForceGenerator

class CollisionFG(ForceGenerator):
    '''Simulate the collision between particles, assuming a collision circle
    around each particle.'''

    # radius around each particle to use for the collision
    COLLISION_RADIUS = 5

    # percent of velocity of each particle retained in collision
    RETAINED = 1.00

    # if the velocity is below this in a collision, set the velocity
    #    of both particles to 0, to prevent them from freaking out
    VELOCITY_CUT_OFF = .1

    #TODO: make sure it the same particles don't collide twice in the loop

    def starting_run(self):
        self.collided = [] # records what has collided, stored as sets

    def act_on_particle(self, p1):
        if not p1.has_attribute(self.generator_name + "_NoCollision"):
            for p2 in self._all_particles:
                displacement_x = p1.position.x - p2.position.x
                displacement_y = p1.position.y - p2.position.y
                dist = math.hypot(displacement_x, displacement_y)
                if (dist < self.COLLISION_RADIUS) and (dist != 0) \
                        and (set([p1, p2]) not in self.collided):
                    # there is a collision
                    self.collided.append(set([p1, p2]))
                    tmp_velocity = Vector(p1.velocity.x, p1.velocity.y)
                    p1.velocity = p2.velocity
                    p2.velocity = tmp_velocity
                    p1.velocity.x *= self.RETAINED
                    p1.velocity.y *= self.RETAINED
                    p2.velocity.x *= self.RETAINED
                    p2.velocity.y *= self.RETAINED
                    # prevent freaking out
                    if p2.velocity.magnitude() < self.VELOCITY_CUT_OFF:
                        p2.velocity.set(0, 0)
                    if p1.velocity.magnitude() < self.VELOCITY_CUT_OFF:
                        p1.velocity.set(0, 0)
